import json
from langchain.chains.llm import LLMChain
from langchain_community.llms.tongyi import Tongyi
from langchain_core.prompts import PromptTemplate
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet
from rest_framework.generics import ListAPIView
from rest_framework.response import Response
from .models import Combo, Goods, Middle, Message, Message2
from .ser import ComboSer, GoodsSer, MessageSer, MiddleSer, Message2Ser
from user.models import User
from homepage.models import HomePage, Cate, HomePage1, HomePage2
import requests
from bs4 import BeautifulSoup
from django.utils import timezone
from elasticsearch import Elasticsearch
from utils.xuehua import xue
from ollama import Client


class RecommendView(APIView):
    def get(self, request):
        good = request.query_params.get('good')
        goods = Goods.objects.get(id=good)
        com = Combo.objects.filter(middle__goods=goods)
        com_ser = ComboSer(com, many=True)
        return Response(com_ser.data)


class GoodsView(ModelViewSet):
    queryset = Goods.objects.all()
    serializer_class = GoodsSer


class CommentView(APIView):
    def get(self, request):
        goods = request.query_params.get('goods')
        goods = Goods.objects.get(id=goods)
        message = Message.objects.filter(goods=goods)
        message_ser = MessageSer(message, many=True)
        return Response(message_ser.data)

    def post(self, request):
        # 获取参数
        user = request.data.get('user')
        goods = request.data.get('goods')
        content = request.data.get('content')
        print(user, goods, content)

        # 使用 Langchain 的 Tongyi 模块判断好评、中评还是差评
        llm = Tongyi()
        prompt_template = PromptTemplate(
            input_variables=["content"],
            template="""你是一名专业的评价分析员，你的任务是根据用户的评价判断其属于好评、中评还是差评。
            以下是用户的评价：{content}。在判断时，请遵循以下标准和限制条件：
            好评意味着用户对产品或服务非常满意，表达了高度的赞扬，可能会提到产品的优点，
            如出色的性能、优质的服务、高性价比、外观精美、超出预期的体验等；
            中评表示用户对产品或服务有一定的满意度，但也可能存在一些小的不满或建议，
            用户可能会认为部分功能未达到预期，但整体上还是可以接受；
            差评表示用户对产品或服务非常不满意，可能会提及质量问题、服务态度不好、严重的性能缺陷、发货延迟、功能与描述不符等问题。
            0：差评，1：中评，2：好评
            请仅回答1、2、3，不允许出现其他无关信息。"""
        )
        chain = LLMChain(llm=llm, prompt=prompt_template)
        rating_result = chain.run({"content": content})
        good = Goods.objects.filter(id=goods).first()
        print(rating_result, good)
        if rating_result == '2':
            good.good_review += 1
        elif rating_result == '1':
            good.mixed_review += 1
        elif rating_result == '0':
            good.bad_review += 1
        good.save()

        # 写入评价表
        comment_data = {
            'user': user,
            'goods': goods,
            'content': content,
            'evaluate': rating_result,
        }
        print(comment_data)
        message = MessageSer(data=comment_data)
        if message.is_valid():
            message.save()
        else:
            return Response({"errors": message.errors}, status=400)
        return Response({"message": "评论成功"}, status=201)


def get_category_tree(message):
    children = message.message2_set.all()  # 获取所有父级
    return {
        'id': message.id,
        'content': message.content,
        'children': [get_category_tree(message) for message in children]  # 递归获父级分类
    }


class MessageView(APIView):
    def get(self, request):
        # 获取商品 ID 参数
        goods = request.query_params.get('goods')

        if goods:
            try:
                # 尝试将商品 ID 转换为整数
                goods = int(goods)
                # 查询指定商品的所有顶级评论
                top = Message2.objects.filter(parent=None, goods_id=goods)
            except ValueError:
                return Response({"error": "商品 ID 必须是整数"}, status=status.HTTP_400_BAD_REQUEST)
        else:
            # 如果没有提供商品 ID，则查询所有顶级评论
            top = Message2.objects.filter(parent=None)

        # 构建评论树
        category_tree = [get_category_tree(message) for message in top]

        # 返回评论树
        return Response(category_tree)

    def post(self, request):
        mes_ser = Message2Ser(data=request.data)
        if mes_ser.is_valid():
            mes_ser.save()
            return Response({"message": "评论成功"}, status=status.HTTP_201_CREATED)
        else:
            return Response({"errors": mes_ser.errors}, status=status.HTTP_400_BAD_REQUEST)


# 豆瓣电影评论页面的 URL（示例：电影《肖申克的救赎》）
DOUBAN_MOVIE_URL = 'https://movie.douban.com/subject/1292052/comments?status=P'


class DoubanCommentView(APIView):
    def get(self, request):
        # 发送 HTTP 请求
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
        }
        response = requests.get(DOUBAN_MOVIE_URL, headers=headers)
        if response.status_code != 200:
            return Response(f"Failed to fetch data: {response.status_code}",
                            status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        # 解析 HTML
        soup = BeautifulSoup(response.text, 'lxml')
        comments = soup.find_all('div', class_='comment-item')

        # 获取或创建默认商品
        goods, _ = Goods.objects.get_or_create(name='肖申克的救赎', defaults={
            'price': '0',
            'image': '',
            'good_review': 0,
            'mixed_review': 0,
            'bad_review': 0,
            'views': 0,
            'sales': 0,
            'is_show': True,
            'desc': '豆瓣电影'
        })

        # 初始化 Tongyi 模型和提示模板
        llm = Tongyi()
        prompt_template = PromptTemplate(
            input_variables=["content"],
            template="""你是一名专业的评价分析员，你的任务是根据用户的评价判断其属于好评、中评还是差评。
            以下是用户的评价：{content}。在判断时，请遵循以下标准和限制条件：
            好评意味着用户对产品或服务非常满意，表达了高度的赞扬，可能会提到产品的优点，
            如出色的性能、优质的服务、高性价比、外观精美、超出预期的体验等；
            中评表示用户对产品或服务有一定的满意度，但也可能存在一些小的不满或建议，
            用户可能会认为部分功能未达到预期，但整体上还是可以接受；
            差评表示用户对产品或服务非常不满意，可能会提及质量问题、服务态度不好、严重的性能缺陷、发货延迟、功能与描述不符等问题。
            0：差评，1：中评，2：好评
            请仅回答 0、1、2，不允许出现其他无关信息。"""
        )
        chain = LLMChain(llm=llm, prompt=prompt_template)

        for comment in comments:
            # 提取评论内容
            content = comment.find('span', class_='short').text.strip()

            # 提取用户名
            username = comment.find('span', class_='comment-info').find('a').text.strip()

            # 获取或创建用户
            user, _ = User.objects.get_or_create(username=username, defaults={'password': 'douban123'})

            # 使用大模型判断好评、中评还是差评
            rating_result = chain.run({"content": content})

            # 创建 Message2 实例
            comment_data = {
                'user': user.id,
                'goods': goods.id,
                'content': content,
                'parent': None,
                'created_time': timezone.now()
            }
            message = Message2Ser(data=comment_data)
            if message.is_valid():
                message.save()
            else:
                return Response({"errors": message.errors}, status=status.HTTP_400_BAD_REQUEST)

            if rating_result == '2':
                goods.good_review += 1
            elif rating_result == '1':
                goods.mixed_review += 1
            elif rating_result == '0':
                goods.bad_review += 1

        goods.save()

        return Response({
            "message": f"成功保存 {len(comments)} 条评论到数据库，好评: {goods.good_review} 条，中评: {goods.mixed_review} 条，"
                       f"差评: {goods.bad_review} 条。"
        }, status=status.HTTP_200_OK)


# 连接到 Elasticsearch
es = Elasticsearch("http://127.0.0.1:9200/", timeout=30)
index_name = "myproject"


class DataView(APIView):

    def get(self, request):
        # 查询数据
        good_list = Goods.objects.all()
        com_list = Combo.objects.all()
        home = HomePage.objects.all()
        cate = Cate.objects.all()

        for i in good_list:
            es.index(index='myproject', body={
                'id': i.id,
                'table_name': 'myproject',
                "image": i.image,
                'name': i.name,
                'type': 'good'
            })

        for i in com_list:
            es.index(index='myproject', body={
                'id': i.id,
                'table_name': 'myproject',
                'name': i.name,
                'type': 'combo'
            })

        for i in cate:
            es.index(index='myproject', body={
                'id': i.id,
                'table_name': 'myproject',
                'name': i.name,
                'type': 'cate'
            })

        for i in home:
            es.index(index='myproject', body={
                'id': i.id,
                'table_name': 'myproject',
                'name': i.title,
                "image": i.image,
                'type': 'homepage'
            })

        return Response({"message": "数据保存成功"}, status=status.HTTP_200_OK)


# 定义查询函数
# def multi_condition_query(stime=None, endtime=None, name=None, gender=None):
#     list = []
#
#     # 添加时间条件（假设时间字段为 'timestamp' 且格式为 ISO 8601）
#     if stime and endtime:
#         time_range_query = {
#             "range": {
#                 "timestamp": {
#                     "gte": stime,  # 开始时间
#                     "lte": endtime
#                 }
#             }
#         }
#         list.append(time_range_query)
#
#     # 添加姓名条件
#     if name:
#         name_query = {
#             "match": {
#                 "name": name
#             }
#         }
#         list.append(name_query)
#
#         # 添加性别条件
#     if gender:
#         gender_query = {
#             "match": {
#                 "gender": gender
#             }
#         }
#         list.append(gender_query)
#
#     # 如果没有 must 条件，则查询所有（可选）
#
#     return list
#
#
# class Search(APIView):
#     def get(self, request):
#         # 示例查询
#         name_condition = request.GET.get('name')  # 可选，设置姓名条件
#
#         query = multi_condition_query(name_condition,)
#
#         query1 = {
#             "query": {
#                 "bool": {
#                     "must": [],
#                     "should": []
#                 }
#             },
#             "from": 0,
#             "size": 10,
#             "_source": ['name', 'age']
#         }
#
#         if len(query) > 0:
#             for i in list:
#                 query1["query"]["bool"]["must"].append(i)
#         else:
#             query1["query"]["match_all"] = {}
#             del query1["query"]["bool"]
#
#             # 打印查询语句
#
#         print(query)
#
#         # 执行查询
#         response = es.search(index=index_name, body=query1)
#
#         # 打印查询结果
#         # print(response)
#         return Response({"message": response}, status=status.HTTP_200_OK)


class Search(APIView):
    def get(self, request):
        # 获取查询参数
        query = request.GET.get('q')  # 搜索关键词

        # 如果没有提供查询关键词，则返回空结果
        if not query:
            return Response({"message": "No search query provided"}, status=status.HTTP_400_BAD_REQUEST)

        # 构建 Elasticsearch 查询
        query_body = {
            "query": {
                "multi_match": {
                    "query": query,  # 搜索关键词
                    "fields": ["name", "title"]  # 只查询 name 和 title 字段
                }
            },
            "from": 0,  # 分页起始位置
            "size": 10,  # 分页大小
            "_source": ["name", "title", "image"]
        }

        # 打印查询语句（调试用）
        # print("Elasticsearch Query:", query_body)

        # 执行查询
        try:
            response = es.search(index=index_name, body=query_body)
            return Response({"message": response}, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


def translate_to_chinese(comment):
    # 从请求数据中获取评论内容
    if comment is None:
        return {"error": "请在请求中提供评论内容。"}
    # 初始化客户端，连接到大模型所在服务器
    client = Client(
        host='http://localhost:11434'  # 大模型所在服务器的地址
    )
    # 构建与大模型交互的消息
    response = client.chat(model='deepseek-r1:1.5b', messages=[
        {
            'role': 'system',
            'content': "严格执行中文润色任务：对用户提供的文章内容进行语言优化，提升表达流畅度与专业性。要求润色后内容控制在200字以内，仅返回润色结果，不添加任何解释、说明等额外内容。"
        },
        {
            'role': 'user',
            'content': comment
        }
    ])
    # 将大模型的响应转换为json
    response1 = response.json()
    # 将json字符串转换为字典
    data = json.loads(response1)
    # 提取大模型响应中的内容
    title = data["message"]["content"]
    # 提取润色结果
    translated_text = title.replace("Translation:", "").strip()
    return translated_text.split('>')[-1]


class SendAddView(APIView):
    def post(self, request):
        # 对图片循环可以存多张图片
        # imgs = ''
        # for i in request.data.get('img'):
        #     imgs += i['objectUrl']+''
        # img = imgs.split(' ')[:-1]
        # print(img)
        text = request.data.get('title')
        print(text)
        # 使用大模型对内容进行润色
        textmodel = translate_to_chinese(text)
        print(textmodel)
        # 用雪花算法生成id
        id = xue.getsnowcode()
        # 调用hash函数对前端传的用户id进行哈希，然后对表的数量取模
        num = hash(request.data.get('userid')) % 3
        if num == 0:
            user = User.objects.get(id=request.data.get('userid'))
            if request.data.get('cate'):
                cate = Cate.objects.get(id=request.data.get('cate'))
            else:
                cate = None
            HomePage.objects.create(id=id, image=request.data.get('image'), title=textmodel,
                                    user=user, like=0, cate=cate, is_show=True, is_recommend=True)
        elif num == 1:
            user = User.objects.get(id=request.data.get('userid'))
            if request.data.get('cate'):
                cate = Cate.objects.get(id=request.data.get('cate'))
            else:
                cate = None
            HomePage1.objects.create(id=id, image=request.data.get('image'), title=textmodel,
                                     user=user, like=0, cate=cate, is_show=True, is_recommend=True)
        else:
            user = User.objects.get(id=request.data.get('userid'))
            if request.data.get('cate'):
                cate = Cate.objects.get(id=request.data.get('cate'))
            else:
                cate = None
            HomePage2.objects.create(id=id, image=request.data.get('image'), title=textmodel,
                                     user=user, like=0, cate=cate, is_show=True, is_recommend=True)
        return Response({"msg": "添加成功！！！"})


# class Cart
